//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   BuiltInCrossSections.hh
 * \author Jeremy Roberts
 * \date   Jul 17, 2011
 * \brief  A few very simple cross-section sets for testing
 * \note   Copyright (C) 2011 Jeremy Roberts. 
 */
//---------------------------------------------------------------------------//
// $Rev::                                               $:Rev of last commit
// $Author:: j.alyn.roberts@gmail.com                   $:Author of last commit
// $Date::                                              $:Date of last commit
//---------------------------------------------------------------------------//

#ifndef BUILTINCROSSSECTIONS_HH_
#define BUILTINCROSSSECTIONS_HH_

#include <vector>
#include <string>

#include "material/Materials.hh"
#include "material/Cross_Section.hh"

namespace slabtran
{

using std::vector;
using std::string;

/*!
 *  \class BuiltInCrossSections
 *  \brief A small collection of very simple cross-sections for testing
 *
 *  This class contains several simple, few group cross-section sets for
 *  testing purposes.  These include
 *  - \em xs1g1m, a one group, one material set with a high scattering ratio
 *  - \em xs1g2m, a one group, two material set with a "moderator" and "fuel"
 *  - \em xs2g4m, a two group, four material set with a "moderator" and
 *    three "fuels"
 *
 *  All sets are represented as structs of the same name.  The number of
 *  groups and materials is set, along with the Legendre order. The
 *  actual data is given in a 2d array of the form
 * \f[
     data = \left(\begin{array}{ccccccccccc}
       \Sigma[m_1,g_1] & \Sigma_a[m_1,g_1] & \Sigma_f[m_1,g_1]
     & \nu[m_1,g_1] & \chi[m_1,g_1]
     & \Sigma_s[l_0,m_1,g_1\gets g_1] & \cdots
     & \Sigma_s[l_L,m_1,g_1\gets g_1]
     & \Sigma_s[l_0,m_1,g_1\gets g_2] & \cdots
     &  \Sigma_s[l_L,m_1,g_1\gets g_G]  \\
       \Sigma[m_1,g_2] & \ldots & & & & & & & & &  \\
       \cdots & & & & & \ddots  & & & & & \vdots \\
       \Sigma[m_M,g_G] & \cdots & & & & \cdots & & & &
     & \Sigma_s[l_L,m_M,g_G\gets g_G] \\
     \end{array}\right)\:,
 * \f]
 *
 *  Included is a build method that constructs \ref Cross_Section objects
 *  to place in a \ref Material object.  This (parsing/generating) code will
 *  likely be used also for a simple input-based cross-section description.
 *
 */
class BuiltInCrossSections
{

public:

  /// Access built in sets via this enumeration.
  enum BUILTINXS
  {
    /// Designates \ref xs1g1m.
    XS1G1M,
    /// Designates \ref xs1g2m.
    XS1G2M,
    /// Designates \ref xs2g4m.
    XS2G4M,
    /// Designates \ref xs6g1m.
    XS6G1M,
    /// end place holder
    END_BUILTINXS
  };

  typedef Materials::SP_materials SP_materials;

  /*!
   *  \brief Constructor
   *
   *  \param setid set id; one of \ref BUILTINXS.
   */
  explicit BuiltInCrossSections(const int setid);

  /*!
   *  \brief Build a \ref Materials object using built in set.
   *
   *  \return       smart pointer to Material object.
   */
  SP_materials build();

private:

  int d_number_groups;
  int d_number_materials;
  int d_legendre_order;
  vector<vector<double> > d_sigma;
  vector<string> d_name;
  string d_mat_name;

  /// resize the data vector
  void set_data(const int *data, const double *sigma, const string *name);

};

//-----------------------------------------------------------------------------
/*! \brief Sample data
 *
 *  int    { number_groups, number_materials, legendre_order }
 *  double { { }, ... }
 */
/*!
 *  \brief One group, one material.
 *
 *  This set is for homogeneous one group problems without fission.  It
 *  includes forward scattering (linear), and has a scattering ratio
 *  of 0.99.
 *
 */
const int xs1g1m[3] =
{ 1, 1, 1 };
const string xs1g1m_name[1] =
{ "moderator" };
const double xs1g1m_sigma[1*7] =
{ 1.00, 0.01, 0.00, 0.00, 0.00, 0.99, 0.20 };

/*!
 *  \brief One group, two material.
 *
 *  This set is for a one group reactor.  It has only isotropic scattering.
 *
 */
const int xs1g2m[3] =
{ 1, 2, 0 };
const string xs1g2m_name[2] =
{ "moderator", "fuel" };
const double xs1g2m_sigma[2*6] =
{ 1.00, 0.50, 0.00, 0.00, 0.00, 0.50,     // "moderator"
  1.00, 0.50, 0.25, 2.40, 1.00, 0.50 };   // "fuel", k_inf = 1.2

/*!
 *  \brief Two group, four material.
 *
 *  This two group, four material set was used in several benchmarks of
 *  the heterogeneous coarse mesh method, e.g. the work of Ilas and
 *  Rahnema and of Mosher.  The references do not provide the absorption
 *  cross-section explicitly.  Here, assuming isotropic scattering in
 *  the lab, we use \f$ \Sigma_a \f$ as computed by balance.  Also, we
 *  assume \f$ \nu = 2.5 \f$, as given in Mosher.
 *
 *  The materials consist of "water", two fuels, and the second fuel
 *  mixed with Gd (i.e. highly absorbing).  The set can be used to model
 *  relatively hetergeneous configurations, which can tax numerical methods.
 *
 *  \refs
 *  Ilas, D. and Rahnema, F. "A Heterogeneous Coarse Mesh Transport Method",
 *  <em>Trans. Th. Stat. Phys.</em>, <b>32</b>, 445 - 471, (2003).
 *  Mosher, S. <em>A Variational Transport Theory Method for Two-Dimensional
 *  Reactor Core Calculations</em>, Ph.D. Thesis, Georgia Tech (2004).
 */
const int xs2g4m[3] =
{ 2, 4, 0 };
const string xs2g4m_name[4] =
{ "moderator", "fuel1", "fuel2", "fuel2+Gd" };
const double xs2g4m_sigma[8*7] =
{
  // water
  0.18900, 0.00030, 0.00000, 0.00000, 0.00000, 0.15070, 0.00000,
  1.46330, 0.00970, 0.00000, 0.00000, 0.00000, 0.03800, 1.45360,
  // fuel I,       k_inf =
  0.22630, 0.00692, 0.00268, 2.50000, 1.00000, 0.20060, 0.00000,
  1.01190, 0.02676, 0.04964, 2.50000, 0.00000, 0.01610, 0.93550,
  // fuel II,      k_inf =
  0.22520, 0.00698, 0.00312, 2.50000, 1.00000, 0.19950, 0.00000,
  0.99150, 0.02842, 0.06168, 2.50000, 0.00000, 0.01560, 0.90140,
  // fuel II + Gd, k_inf =
  0.21730, 0.01126, 0.00224, 2.50000, 1.00000, 0.19020, 0.00000,
  1.06060, 0.47982, 0.00748, 2.50000, 0.00000, 0.01360, 0.57330
};

/*
 * \brief one material six group for testing output
 *
 *
 */
const int xs6g1m[3] =
{ 6, 1, 1 };
const string xs6g1m_name[1] =
{ "moderator" };
const double xs6g1m_sigma[6*17] =
{
  //    T        A        F        N        X |      g<-0       |      g<-1       |      g<-2       |      g<-3       |      g<-4       |      g<-5      |
  0.10000, 0.01000, 0.00100, 0.00010, 0.00001, 0.11000, 0.01100, 0.12000, 0.01200, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, // 0
  0.20000, 0.02000, 0.00200, 0.00020, 0.00002, 0.21000, 0.02100, 0.22000, 0.02200, 0.23000, 0.02300, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, // 1
  0.30000, 0.03000, 0.00300, 0.00030, 0.00003, 0.31000, 0.03100, 0.32000, 0.03200, 0.33000, 0.03300, 0.34000, 0.03400, 0.00000, 0.00000, 0.00000, 0.00000, // 2
  0.40000, 0.04000, 0.00400, 0.00040, 0.00004, 0.00000, 0.00000, 0.42000, 0.04200, 0.43000, 0.04300, 0.44000, 0.04400, 0.45000, 0.04500, 0.00000, 0.00000, // 3
  0.50000, 0.05000, 0.00500, 0.00050, 0.00005, 0.00000, 0.00000, 0.00000, 0.00000, 0.53000, 0.05300, 0.54000, 0.05400, 0.55000, 0.05500, 0.56000, 0.05600, // 4
  0.60000, 0.06000, 0.00600, 0.00060, 0.00006, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.64000, 0.06400, 0.65000, 0.06500, 0.66000, 0.06600  // 5
};

} // end namespace slabtran

#endif /* BUILTINCROSSSECTIONS_HH_ */

//---------------------------------------------------------------------------//
//              end of BuiltInCrossSections.hh
//---------------------------------------------------------------------------//
